/*

	Clean data:
	
	List<Account> accList = [select ID from Account];
	delete accList;
	List<Transaction_XML__c> trList = [select ID from Transaction_XML__c];
	delete trList;
	List<Transaction_Header__c> thList = [select ID from Transaction_Header__c];
	delete thList;
	List<Subscriptions__c> subList = [select ID from Subscriptions__c];
	delete subList;

	List<AT_Debug_Log__c> logList = [select ID from AT_Debug_Log__c];
	delete logList;
	
	
*/
global class NA_NotificationHistory
{

	// A class to accept as an input records (e.g. data combinations)
    global class nfInputs
    {
        webservice integer RowId;
        webservice String Kind;
        webservice String Content;
    }
 
    // A class to send back as an output
	global class nfOutputs
	{
		webservice ID AccountID;
	}
 
    // The actual web service method we will call
	webservice static nfOutputs HistoryNotificationRequest(nfInputs inputs)
	{
		nfOutputs output = new nfOutputs();
		output.AccountID = null;
		
		if(inputs!=null && inputs.Content!=null && inputs.Content.trim()!='')
		{
			Transaction_XML__c newTXML = new Transaction_XML__c();
			newTXML.Row_ID__c = inputs.RowId;
			newTXML.Kind__c = inputs.Kind;
			newTXML.FS_Notification__c = inputs.Content.replace('\\\"','\"');
			insert newTXML;
	
			output.AccountID = DataProcessing(newTXML);
		}

		return output;
	}
	
	
	private static ID DataProcessing(Transaction_XML__c inTXML)
	{

		Transaction_Header__c THItem = parseXML(inTXML);
    	Account accItem = asertAccount(THItem);
    	if(accItem!=null)
    	{
    		inTXML.Account__c = accItem.ID;
    		update inTXML;
    		THItem.Account__c = accItem.ID;
    		update THItem;
    	}
    	if(THItem!=null)
    	{
    		createLicenseItems(THItem);
    		AT_sendIntacctCallOut.sendToInTacct(THItem.ID);
    	}
    	
		
		return accItem==null?null:accItem.ID;
	}
	

	
	private static void createLicenseItems(Transaction_Header__c THItem)
	{
		System.debug('>>>>>>>>>>>>>>>>>>>> createLicenseItems start!!!!');
		if(THItem!=null && THItem.Account__c!=null)
		{
			List<Licenses__c> LicenseItemList = new List<Licenses__c>();
			map<String, String> CouponProductMap = getCouponProducts();
			System.debug('>>>>>>>>>>>>>>>>>>>> THItem ID='+THItem.ID);
			for(Transaction_Detail__c TDItem : [select FS_File_URL__c, FS_File_Key__c, FS_License_Key__c,FS_License_Data__c, FS_License_Name__c, FS_Product_Name__c, Product__c,Transaction_Header__c
											from Transaction_Detail__c where Transaction_Header__c=:THItem.ID])
			{
				System.debug('>>>>>>>>>>>>>>>>>>>> TDItem ID='+TDItem.ID);
				System.debug('>>>>>>>>>>>>>>>>>>>> TDItem FS_License_Key__c='+TDItem.FS_License_Key__c);
				if(TDItem.FS_License_Key__c!=null || TDItem.FS_File_Key__c!=null)
				{
					//(TDItem.FS_License_Key__c=='mac_license' || TDItem.FS_License_Key__c=='win_file')
					Licenses__c LicensesItem = new Licenses__c();
					LicensesItem.Account__c = THItem.Account__c;
					LicensesItem.Product__c = TDItem.Product__c;
					LicensesItem.Product_Name__c = TDItem.FS_Product_Name__c;
					LicensesItem.Reference_Number__c = THItem.FS_Reference_Number__c;
					
					if(CouponProductMap.containsKey(LicensesItem.Product_Name__c)){ LicensesItem.Coupon__c = TDItem.FS_License_Data__c;}
					else if(TDItem.FS_License_Key__c=='mac_license'){ LicensesItem.Mac_License__c = TDItem.FS_License_Data__c;}
					else if(TDItem.FS_License_Key__c=='win_license'){ LicensesItem.Win_License__c = TDItem.FS_License_Data__c;}
					
					if(TDItem.FS_File_Key__c=='mac_file'){ LicensesItem.Mac_File__c = TDItem.FS_File_URL__c;}
					else if(TDItem.FS_File_Key__c=='win_file'){ LicensesItem.Win_File__c = TDItem.FS_File_URL__c;}
					
					LicenseItemList.add(LicensesItem);
				}
			}

			if(LicenseItemList.size()>0) insert LicenseItemList;
		}
	}
	
	private static String CountryCode2LocationName(String inCountryCode)
	{
		String retValue = '';
		List<AT_Country2LocationName__c> CLNList = AT_Country2LocationName__c.getall().values();
		map<String, String> mapCountryCode2LocationName = new map<String, String>();
		if(CLNList!=null && CLNList.size()>0)
		{
			for(AT_Country2LocationName__c item:CLNList){ mapCountryCode2LocationName.put(item.CountryCode__c,item.Name);}
			
			if(inCountryCode!=null && inCountryCode!='' && mapCountryCode2LocationName.containsKey(inCountryCode))
			{
				retValue = mapCountryCode2LocationName.get(inCountryCode);
			}
			else
			{
				retValue = mapCountryCode2LocationName.get('ELSE');
			}
		}
		return retValue;
	}
	
	private static map<String, String> getCouponProducts()
	{
		map<String, String> retCouponProductsMap = new map<String, String>();
		List<AT_Coupon_Products__c> CLNList = AT_Coupon_Products__c.getall().values();
		if(CLNList!=null && CLNList.size()>0)
		{
			for(AT_Coupon_Products__c item:CLNList){ retCouponProductsMap.put(item.Name,item.Name);}
		}
		return retCouponProductsMap;
	}
	
	private static Transaction_Header__c parseXML (Transaction_XML__c inTXML)
	{
		TG_XmlDom dom = new TG_XmlDom(inTXML.FS_Notification__c);
    	TG_XmlNode root = dom.root;
    	TG_XmlNode orderXN = null; 
    	
    	orderXN = root.getElementByTagName('order');
    	if(orderXN==null) orderXN = root.getElementByTagName('return');
    	if(orderXN==null) return null;
    	
    	TG_XmlNode orderPurchaserXN = orderXN.getElementByTagName('purchaser');
    	TG_XmlNode orderItemsXN = orderXN.getElementByTagName('items');
    	//TG_XmlNode orderDateXN = orderXN.getElementByTagName('date');
    	//system.debug('>>>>>>>>>>> '+orderDateXN.textContent);

    	Transaction_Header__c THItem = new Transaction_Header__c();
    	try{ THItem.FS_Date__c = datetime.valueOf(orderXN.getElementByTagName('date').textContent);}
    	catch(Exception ex){ THItem.FS_Date__c = null;}

    	if(orderXN.getElementByTagName('reference')!=null) THItem.FS_Reference_Number__c = orderXN.getElementByTagName('reference').textContent;
    	if(orderXN.getElementByTagName('referrer')!=null) THItem.FS_Referrer__c = AT_Utils.parseURL(orderXN.getElementByTagName('referrer').textContent);
    	
    	// Added by Ted's request three fields 20/1/2011 
    	if(orderXN.getElementByTagName('sourceName')!=null) THItem.FS_SourceName__c = orderXN.getElementByTagName('sourceName').textContent;
    	if(orderXN.getElementByTagName('sourceKey')!=null) THItem.FS_SourceKey__c = orderXN.getElementByTagName('sourceKey').textContent;
    	if(orderXN.getElementByTagName('sourceCampaign')!=null) THItem.FS_SourceCampaign__c = orderXN.getElementByTagName('sourceCampaign').textContent;
    	
    	THItem.Class_Name__c = 'CONSUMER';
    	if(orderXN.getElementByTagName('currency')!=null) THItem.CurrencyIsoCode = orderXN.getElementByTagName('currency').textContent;

    	try{ THItem.FS_Tax__c = double.valueOf(orderXN.getElementByTagName('tax').textContent);}
    	catch(Exception ex){ THItem.FS_Tax__c = null;}
    	
    	try{ THItem.FS_Total__c = double.valueOf(orderXN.getElementByTagName('total').textContent);}
    	catch(Exception ex){ THItem.FS_Total__c = null;}

    	try{ THItem.FS_Subtotal__c = double.valueOf(orderXN.getElementByTagName('subtotal').textContent);}
    	catch(Exception ex){ THItem.FS_Subtotal__c = null;}
    	
    	if(orderXN.getElementByTagName('currency')!=null) THItem.FS_Currency__c = orderXN.getElementByTagName('currency').textContent;

    	
    	try{ THItem.FS_SubtotalUSD__c = double.valueOf(orderXN.getElementByTagName('subtotalUSD').textContent);}
    	catch(Exception ex){ THItem.FS_SubtotalUSD__c = null;}
    	
		
		try{ THItem.FS_Type__c = orderXN.getElementByTagName('type').textContent;}
		catch(Exception ex){ THItem.FS_Type__c = null;}
		try{ THItem.FS_Reason__c = orderXN.getElementByTagName('reason').textContent;}
		catch(Exception ex){ THItem.FS_Reason__c = null;}

    	
    	if(orderPurchaserXN!=null)
    	{
	    	if(orderPurchaserXN.getElementByTagName('fname')!=null) THItem.FS_Purchaser_First_Name__c = orderPurchaserXN.getElementByTagName('fname').textContent;
	    	if(orderPurchaserXN.getElementByTagName('lname')!=null) THItem.FS_Purchaser_Last_Name__c = orderPurchaserXN.getElementByTagName('lname').textContent;
	    	if(orderPurchaserXN.getElementByTagName('company')!=null) THItem.FS_Purchaser_Company__c = orderPurchaserXN.getElementByTagName('company').textContent;
	    	if(orderPurchaserXN.getElementByTagName('email')!=null) THItem.FS_Purchaser_Email__c = orderPurchaserXN.getElementByTagName('email').textContent;
	    	if(orderPurchaserXN.getElementByTagName('phone')!=null) THItem.FS_Purchaser_Phone__c = orderPurchaserXN.getElementByTagName('phone').textContent;
	    	
	    	if(orderPurchaserXN.getElementByTagName('country')!=null) THItem.FS_Purchaser_Country__c = orderPurchaserXN.getElementByTagName('country').textContent;
	    	
	    	if(orderPurchaserXN.getElementByTagName('region')!=null) THItem.FS_Purchaser_Region__c = orderPurchaserXN.getElementByTagName('region').textContent;
	    	if(orderPurchaserXN.getElementByTagName('address1')!=null) THItem.FS_Purchaser_Address1__c = orderPurchaserXN.getElementByTagName('address1').textContent;
	    	if(orderPurchaserXN.getElementByTagName('address2')!=null) THItem.FS_Purchaser_Address2__c = orderPurchaserXN.getElementByTagName('address2').textContent;
	    	if(orderPurchaserXN.getElementByTagName('city')!=null) THItem.FS_Purchaser_City__c = orderPurchaserXN.getElementByTagName('city').textContent;
	    	if(orderPurchaserXN.getElementByTagName('postal')!=null) THItem.FS_Purchaser_Postal_Code__c = orderPurchaserXN.getElementByTagName('postal').textContent;
    	}

    	
    	if(THItem.FS_Purchaser_Country__c!=null) THItem.Location_Name__c = CountryCode2LocationName(THItem.FS_Purchaser_Country__c);
    	THItem.Transaction_XML__c = inTXML.ID;
    	insert THItem;

    	
    	/*
    	Start Block for insert Transaction Detail Records & License Records
    	*/
    	if(orderItemsXN!=null)
    	{
	    	List<TG_XmlNode> oItemsList = orderItemsXN.getElementsByTagName('item');
	    	if(oItemsList!=null && oItemsList.size()>0)
	    	{
	    		List<Transaction_Detail__c> TDItemList = new List<Transaction_Detail__c>();
	    		//List<Licenses__c> LicenseItemList = new List<Licenses__c>();
	    		List<String> productCodeList = new List<String>();
	    		map<String,ID> mapProductCode2ID = new map<String,ID>();
	    		for(TG_XmlNode oItemXN:oItemsList)
	    		{
	    			String strProductCode = null;
	    			if(oItemXN.getElementByTagName('product')!=null) strProductCode = oItemXN.getElementByTagName('product').textContent;
	    			if(strProductCode!=null && strProductCode!='')
	    			{
	    				productCodeList.add(strProductCode);
	    				mapProductCode2ID.put(strProductCode, null);
	    			}
	    		}
	    		
	    		if(productCodeList.size()>0)
	    		{
	    			for(Product2 item:[Select Id,ProductCode From Product2 where ProductCode in :productCodeList])
	    			{
	    				mapProductCode2ID.put(item.ProductCode, item.Id);
	    			}
	    		}
	    		
	    		for(TG_XmlNode oItemXN:oItemsList)
	    		{
	    			TG_XmlNode oItemLicenseXN = null;
	    			TG_XmlNode oItemFileXN = null;
	    			Transaction_Detail__c itemTD = new Transaction_Detail__c();
	    			itemTD.Transaction_Header__c = THItem.ID;
	    			if(oItemXN.getElementByTagName('product')!=null) itemTD.FS_Product_Name__c = oItemXN.getElementByTagName('product').textContent;
	    			if(itemTD.FS_Product_Name__c!=null && itemTD.FS_Product_Name__c!='')
	    			{
	    				itemTD.Product__c = mapProductCode2ID.get(itemTD.FS_Product_Name__c);
	    			}
	    			try{ itemTD.FS_Quantity__c = integer.valueOf(oItemXN.getElementByTagName('quantity').textContent);}
	    			catch(Exception ex){ itemTD.FS_Quantity__c = null;}
	    			
	    			try{ itemTD.FS_Subtotal__c = double.valueOf(oItemXN.getElementByTagName('subtotal').textContent);}
	    			catch(Exception ex){ itemTD.FS_Subtotal__c = null;}
	    			
	    			
	    			try{ itemTD.FS_SubtotalUSD__c = double.valueOf(oItemXN.getElementByTagName('priceTotalUSD').textContent);}
	    			catch(Exception ex){ itemTD.FS_SubtotalUSD__c = null;}
	    			
	
	
					if(oItemXN.getElementByTagName('licenses')!=null)
	    			{
	    				oItemLicenseXN = oItemXN.getElementByTagName('licenses').getElementByTagName('license');
	    			}
					if(oItemXN.getElementByTagName('files')!=null)
	    			{
	    				oItemFileXN = oItemXN.getElementByTagName('files').getElementByTagName('file');
	    			}
	    			
	    			if(oItemLicenseXN!=null)
	    			{
	    				if(oItemLicenseXN.getElementByTagName('key')!=null) itemTD.FS_License_Key__c = oItemLicenseXN.getElementByTagName('key').textContent;
	    				if(oItemLicenseXN.getElementByTagName('name')!=null) itemTD.FS_License_Name__c = oItemLicenseXN.getElementByTagName('name').textContent;
	    				if(oItemLicenseXN.getElementByTagName('data')!=null) itemTD.FS_License_Data__c = oItemLicenseXN.getElementByTagName('data').textContent;
	    			}
	    			
	    			if(oItemFileXN!=null)
	    			{
	    				if(oItemFileXN.getElementByTagName('key')!=null) itemTD.FS_File_Key__c = oItemFileXN.getElementByTagName('key').textContent;
	    				if(oItemFileXN.getElementByTagName('url')!=null) itemTD.FS_File_URL__c = oItemFileXN.getElementByTagName('url').textContent;
	    			}
	    			
	    			TDItemList.add(itemTD);
	    		}
	    		
	    		if(TDItemList.size()>0) insert TDItemList;
	    	}
    	}
    	/*
    	End Block for insert Transaction Detail Records & License Records
    	*/
    	
    	
    	
    	return THItem;
	}
	
	private static Account asertAccount(Transaction_Header__c inTHItem)
	{
		if(inTHItem == null) return null;

		Account accItem = null;
		RecordType PersonalAccountRT = [SELECT ID FROM RecordType WHERE SobjectType='Account' AND IsPersonType=True limit 1];

		accItem = new Account(RecordTypeId = PersonalAccountRT.ID);
		
		if(
			(inTHItem.FS_Referrer__c!=null && inTHItem.FS_Referrer__c!='') ||
			(inTHItem.FS_Purchaser_Email__c!=null && inTHItem.FS_Purchaser_Email__c!='')			
		)
		{
			//String queryTxt = 'select Id from Account';
			String queryTxt = '';
			if(inTHItem.FS_Referrer__c!=null && inTHItem.FS_Referrer__c!='') queryTxt = 'Referrer__c=\''+inTHItem.FS_Referrer__c+'\'';
			if(inTHItem.FS_Purchaser_Email__c!=null && inTHItem.FS_Purchaser_Email__c!='')
			{ 
				if(queryTxt!='') queryTxt +=' OR ';  
				queryTxt = 'PersonEmail=\''+inTHItem.FS_Purchaser_Email__c+'\'';
			}
			// a.BillingStreet, a.BillingState, a.BillingPostalCode, a.BillingCountry, a.BillingCity
			queryTxt  = 'select ID, Referrer__c,Company__c, FirstName, LastName, BillingStreet, BillingState,'+ 
							'BillingPostalCode, BillingCountry, BillingCity, PersonDepartment,'+
							'PersonEmail, Phone from Account where '+queryTxt+' limit 1';
			for(Account item:Database.query(queryTxt))
			{
				accItem = item;
			}
		}
		
		if((inTHItem.FS_Referrer__c!=null && inTHItem.FS_Referrer__c!='')) accItem.Referrer__c = inTHItem.FS_Referrer__c;
		if((inTHItem.FS_Purchaser_Email__c!=null && inTHItem.FS_Purchaser_Email__c!='')) accItem.PersonEmail = inTHItem.FS_Purchaser_Email__c;
		
		accItem.FirstName = (inTHItem.FS_Purchaser_First_Name__c!=null && inTHItem.FS_Purchaser_First_Name__c.length()>80)?inTHItem.FS_Purchaser_First_Name__c.substring(0,80):inTHItem.FS_Purchaser_First_Name__c;
		accItem.LastName = (inTHItem.FS_Purchaser_Last_Name__c!=null && inTHItem.FS_Purchaser_Last_Name__c.length()>80)?inTHItem.FS_Purchaser_Last_Name__c.substring(0,80):inTHItem.FS_Purchaser_Last_Name__c;
		accItem.Company__c = (inTHItem.FS_Purchaser_Company__c!=null && inTHItem.FS_Purchaser_Company__c.length()>80)?inTHItem.FS_Purchaser_Company__c.substring(0,80):inTHItem.FS_Purchaser_Company__c;
		accItem.Phone = inTHItem.FS_Purchaser_Phone__c;
		accItem.BillingCountry = (inTHItem.FS_Purchaser_Country__c!=null && inTHItem.FS_Purchaser_Country__c.length()>40)?inTHItem.FS_Purchaser_Country__c.substring(0,40):inTHItem.FS_Purchaser_Country__c;
		accItem.BillingState = (inTHItem.FS_Purchaser_Region__c!=null && inTHItem.FS_Purchaser_Region__c.length()>20)?inTHItem.FS_Purchaser_Region__c.substring(0,20):inTHItem.FS_Purchaser_Region__c;
		accItem.BillingCity = (inTHItem.FS_Purchaser_City__c!=null && inTHItem.FS_Purchaser_City__c.length()>40)?inTHItem.FS_Purchaser_City__c.substring(0,40):inTHItem.FS_Purchaser_City__c;
		accItem.BillingPostalCode = (inTHItem.FS_Purchaser_Postal_Code__c!=null && inTHItem.FS_Purchaser_Postal_Code__c.length()>20)?inTHItem.FS_Purchaser_Postal_Code__c.substring(0,20):inTHItem.FS_Purchaser_Postal_Code__c;
		if(inTHItem.FS_Purchaser_Address1__c!=null || inTHItem.FS_Purchaser_Address2__c!=null)
		{
			accItem.BillingStreet = (inTHItem.FS_Purchaser_Address1__c!=null?inTHItem.FS_Purchaser_Address1__c:'')+' '+(inTHItem.FS_Purchaser_Address2__c!=null?inTHItem.FS_Purchaser_Address2__c:'');
			accItem.BillingStreet = accItem.BillingStreet.trim();
		}
		else accItem.BillingStreet = null;
		
		try
		{
			upsert accItem;
		}
		catch(Exception ex){ return null;}
		
		return accItem;
	}

}